// AWTContainer.cpp: implementation of the AWTContainer class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "AWT.h"
#include "AWTContainer.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

IMPLEMENT_DYNAMIC(AWTContainer, AWTComponent)

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

AWTContainer::AWTContainer()
{
	m_ncomponents = 0;
	m_layoutManager = NULL;
	m_insets = AWTInsets(0,0,0,0);
}

AWTContainer::~AWTContainer()
{
	removeAll();
	if (m_layoutManager != NULL)
		delete m_layoutManager;
}

AWTComponent* AWTContainer::getComponent(int n)
{
	if ((n < 0) || (n >= m_ncomponents))
		return NULL;
	else
		return (AWTComponent*)m_components.GetAt(n);
}

void AWTContainer::addImpl(AWTComponent* comp, CString& constraints, int index)
{
	if (comp == NULL)
		return;
	if (index > m_ncomponents || (index < 0 && index != -1))
		return;

	AWTContainer* p = (AWTContainer*)comp->getParent();
	if (p != NULL)
	{
		p->remove(comp);
	}
	
	if (index != -1)
		m_components.InsertAt(index, comp);
	else
		m_components.Add(comp);
	m_ncomponents++;

	comp->setParent(this);

	comp->addNotify();

	if (m_valid)
		invalidate();

	AWTLayoutManager* layout = getLayout();

	if (layout != NULL)
//		((AWTLayoutManager*)m_layoutManager)->addLayoutComponent((CString*)&constraints, comp);
		layout->addLayoutComponent((CString*)&constraints, comp);


	if (!constraints.IsEmpty())
		comp->setName(constraints); //used by tabbed form (name is tab text)

//	componentAdded(comp);

}
/*
void AWTContainer::componentAdded(AWTComponent* comp)
{
	if (m_parent != NULL) 
	{
		((AWTContainer*)m_parent)->componentAdded(comp);
	}
}
*/
void AWTContainer::remove(int index)
{
	if ((index < 0) || (index >= m_ncomponents))
		return;
	AWTComponent* comp = (AWTComponent*)m_components[index];
	if (comp == NULL)
		return;
	m_components.RemoveAt(index);		
	m_ncomponents--;
	comp->removeNotify();
	if (m_valid)
		invalidate();
	if (m_layoutManager != NULL)
		((AWTLayoutManager*)m_layoutManager)->removeLayoutComponent(comp);
	delete comp;
}

void AWTContainer::remove(AWTComponent* comp)
{
	for (int n = 0; n < m_ncomponents; n++)
	{
		if (comp == (AWTComponent*)m_components[n])
			remove(n);
	}

}

void AWTContainer::removeAll()
{
	int i = m_ncomponents;
	for (int n = 0; n < i; n++)
		remove(0); //deliberately 0!
	m_components.RemoveAll();
	m_ncomponents = 0;
	if (m_valid)
		invalidate();
}

void AWTContainer::setLayout(AWTLayout* mgr)
{
	if (m_layoutManager != NULL)
		delete m_layoutManager;
	m_layoutManager = mgr;
	if (m_valid) 
		invalidate();
}

void AWTContainer::doLayout()
{
	AWTLayoutManager* layoutMgr = getLayout();
	if (layoutMgr != NULL) 
	    layoutMgr->layoutContainer(this);
}

void AWTContainer::validate() 
{
	if (!m_valid) 
	{
		validateTree();
		m_valid = TRUE;
  }
}

void AWTContainer::validateTree() 
{
	if (!m_valid) 
	{
		doLayout();
		for (int n = 0; n < m_ncomponents; n++)
		{
			AWTComponent* comp = (AWTComponent*)m_components[n];
			comp->validate();
		}
		m_valid = TRUE;
	}
}

void AWTContainer::addNotify() 
{
	AWTComponent::addNotify();
	for (int n = 0; n < m_ncomponents; n++)
	{
		AWTComponent* comp = (AWTComponent*)m_components[n];
		comp->addNotify();
	}
}

void AWTContainer::removeNotify() 
{
	for (int n = 0; n < m_ncomponents; n++)
	{
		AWTComponent* comp = (AWTComponent*)m_components[n];
		comp->removeNotify();
	}
	AWTComponent::removeNotify();
}

CSize AWTContainer::preferredSize() 
{
	if (m_layoutManager == NULL)
		return AWTComponent::preferredSize();

	AWTLayoutManager* lm = m_layoutManager->getLayoutManager();
	if (lm != NULL)
	{
		m_prefSize = lm->preferredLayoutSize(this);
		return m_prefSize;
	}
	return AWTComponent::minimumSize();
}

CSize AWTContainer::minimumSize() 
{
	if (m_layoutManager == NULL)
		return AWTComponent::minimumSize();

	AWTLayoutManager* lm = m_layoutManager->getLayoutManager();
	if (lm != NULL)
	{
		m_minSize = lm->minimumLayoutSize(this);
		return m_minSize;
	}
	return AWTComponent::minimumSize();
}

void AWTContainer::nextFocus(AWTComponent* base) 
{
	if (m_parent != NULL) 
	{
		m_parent->transferFocus(base);
	}
}

void AWTContainer::eraseBackground(CDC* pDC)
//void AWTContainer::eraseBkground(CDC* pDC) 
{
	CRect rcThis = CRect(0,0,getSize().cx, getSize().cy);
	CRgn clipRgn;
	clipRgn.CreateRectRgnIndirect(&rcThis);
	pDC->SelectClipRgn(&clipRgn);
	for (int n = 0; n < m_ncomponents; n++)
	{
		AWTComponent* comp = (AWTComponent*)m_components[n];
		if (comp->isVisible())
		{
			CRect rc = comp->getBounds();
			// create clipping region
			pDC->ExcludeClipRect(&rc);
		}
	}

	AWTComponent::eraseBackground(pDC);

	pDC->SelectClipRgn(NULL);
}
